﻿using System;
using System.ComponentModel;
using NHibernate;
using NHibernate.Proxy.DynamicProxy;

namespace PurchaseSales.Manage.Common.AOP
{
    public class NotifyPropertyChangedInterceptor : EmptyInterceptor
    {
        private ISession session = null;

        private static readonly ProxyFactory factory = new ProxyFactory();

        public override void SetSession(ISession session)
        {
            this.session = session;
            base.SetSession(session);
        }

        public override Object Instantiate(String clazz, EntityMode entityMode, Object id)
        {
            Type entityType = Type.GetType(clazz);
            IProxy proxy = factory.CreateProxy(entityType, new BaseInterceptor(), typeof(INotifyPropertyChanged)) as IProxy;

            BaseInterceptor interceptor = proxy.Interceptor as BaseInterceptor;
            interceptor.Proxy = this.session.SessionFactory.GetClassMetadata(entityType).Instantiate(id, entityMode);

            this.session.SessionFactory.GetClassMetadata(entityType).SetIdentifier(proxy, id, entityMode);

            return (proxy);
        }

    }

    public class EntityFactory
    {
        private ProxyFactory _factory = new ProxyFactory();
        private ISession session = null;

        public EntityFactory(ISession session)
        {
            this.session = session;
        }

        public T Create<T>()
        {
            var type = typeof(T);
            var proxy = _factory.CreateProxy(type, new BaseInterceptor(), typeof(INotifyPropertyChanged)) as IProxy;
            BaseInterceptor interceptor = proxy.Interceptor as BaseInterceptor;
            var id = default(Guid);
            interceptor.Proxy = this.session.SessionFactory.GetClassMetadata(type).Instantiate(id, EntityMode.Poco);
            this.session.SessionFactory.GetClassMetadata(type).SetIdentifier(proxy, id, EntityMode.Poco);

            return (T)proxy;
        }
    }
}
